#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "app.h"
#include "concert_ticket.h"
#include "list.h"
#include "debug.h"
#include "input_judge.h"

static int save_concert_ticket(struct list_head *p_ticket_head);
static int load_concert_ticket(struct list_head *p_ticket_head);
static struct concert_ticket *locate_concert_ticket(struct list_head *p_ticket_head, char *ID);
static int save_user_info(struct user_info *p_user_info, struct list_head *p_booked_ticket_id_head);


int concert_ticket_init(struct list_head *p_ticket_head,
						struct list_head *p_booked_ticket_id_head)
{
	int ret, count;
	FILE *fp_concert_ticket = NULL;
	char *data;
	struct concert_ticket concert_ticket_data[3] = {
		{"A0001", "张敬轩", "6.8", "780", "70", "70"},
		{"A0002", "陈奕迅", "1.1", "780", "70", "70"},
		{"A0003", "卫兰", "3.2", "780", "70", "70"}
	};
	
	if (!p_ticket_head ||
		!p_booked_ticket_id_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	if (access(LIB_DIR, F_OK) != 0)
		mkdir(LIB_DIR, 0777);

	if (access(CONCERT_TICKET_FILE, F_OK) != 0) {
		fp_concert_ticket = fopen(CONCERT_TICKET_FILE, "ab+");
		if (!fp_concert_ticket) {
			DEBUG("加载门票失败,文件打开失败\n");
			return (-TICKET_OPEN_FILE_FAIL);
		}
		
		for (count = 0; count < 3;count++) {
			if(fwrite(&concert_ticket_data[count],
					  sizeof(struct concert_ticket),
					  1,
					  fp_concert_ticket) != 1) {
				DEBUG("fwrite error");
				fclose(fp_concert_ticket);
				return (-TICKET_WRITE_FILE_FAIL);
			}
		}

		fclose(fp_concert_ticket);
	}

	init_list_head(p_ticket_head);
	ret = load_concert_ticket(p_ticket_head);

	init_list_head(p_booked_ticket_id_head);

	return ret;
}


int display_concert_ticket(struct list_head *p_ticket_head,int num)
{
	struct list_head *next, *head;
	int count = 0, ticket_num = 0;
	struct concert_ticket *p_concert_ticket_data = NULL;

	if (!p_ticket_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	head = p_ticket_head;
	list_for_each(next, head) {
		ticket_num++;
	}

	printf("  ID   艺人   时间   价格   余/总票数");
	MOVEDOWN(2);
	MOVELEFT(46);

	list_for_each(next, head) {
		p_concert_ticket_data = list_entry(next, struct concert_ticket, list);
		if(count < num) {
			printf("%s   %s   %s   %s   %s/%s",
				p_concert_ticket_data->ID, p_concert_ticket_data->artist,
				p_concert_ticket_data->show_time, p_concert_ticket_data->price,
				p_concert_ticket_data->spare_ticket_num, p_concert_ticket_data->total_ticket_num);
			
			MOVEDOWN(2);
			MOVELEFT((int)(strlen(p_concert_ticket_data->ID) +
						   strlen(p_concert_ticket_data->artist) +
						   strlen(p_concert_ticket_data->show_time) +
						   strlen(p_concert_ticket_data->price) +
						   strlen(p_concert_ticket_data->spare_ticket_num) +
						   strlen(p_concert_ticket_data->total_ticket_num))+10);

		}
		count++;
	}

	return TRUE;
}


static int save_concert_ticket(struct list_head *p_ticket_head)
{
	struct list_head *next, *head;
	struct concert_ticket *p_concert_ticket_data = NULL;
	FILE *fp_concert_ticket = NULL;
    
	if (!p_ticket_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	fp_concert_ticket = fopen(CONCERT_TICKET_FILE, "wb");
	if (!fp_concert_ticket) {
		DEBUG("文件打开失败\n");
		return (-TICKET_WRITE_FILE_FAIL);
	}

	head = p_ticket_head;
	list_for_each(next, head) {
		p_concert_ticket_data = list_entry(next, struct concert_ticket, list);

		if (fwrite(p_concert_ticket_data, sizeof(struct concert_ticket), 1, fp_concert_ticket != 1)
			DEBUG("fwrite error");
	}

	fclose(fp_concert_ticket);

	return TRUE;
}

static int load_concert_ticket(struct list_head *p_ticket_head)
{
	FILE *fp_concert_ticket = NULL;
	struct train_ticket *p_concert_ticket_next;

	if (!p_ticket_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	fp_concert_ticket = fopen(CONCERT_TICKET_FILE, "ab+");
	if (!fp_concert_ticket) {
		DEBUG("加载门票失败,文件打开失败\n");
		return (-TICKET_OPEN_FILE_FAIL);
	}

	while (!feof(fp_concert_ticket)) {
		p_concert_ticket_next = (struct concert_ticket *)malloc(sizeof(struct concert_ticket));
		if (fread(p_concert_ticket_next, 
				  sizeof(struct concert_ticket), 1, fp_concert_ticket) == 1) {
			list_add_tail(&p_concert_ticket_next->list, p_ticket_head);
		}
		else {
			free(p_concert_ticket_next);
		}

	}

	fclose(fp_concert_ticket);
	return TRUE;

}


static struct concert_ticket *locate_concert_ticket(struct list_head *p_ticket_head, char *ID)
{
	struct list_head *next, *head;
	struct concert_ticket *p_concert_ticket_data = NULL;
	if (!p_ticket_head || !ID) {
		DEBUG("PARAM ERROR!\n");
		return NULL;
	}

	head = p_ticket_head;
	list_for_each(next, head) {
		p_concert_ticket_data = list_entry(next, struct concert_ticket, list);
		if(!strcmp(p_concert_ticket_data->ID, ID))
			return p_concert_ticket_data;
	}

	return NULL;
}


int load_user_info(char *account,
				   struct user_info *p_user_info,
				   struct list_head *p_booked_ticket_id_head)
{
	uint8_t count;
	struct list_head *next = NULL;
	struct list_head *head = NULL;
	struct user_info user_info_data;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;
	FILE *fp_user_info = NULL;

	if(!account || !p_user_info || !p_booked_ticket_id_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	head = p_booked_ticket_id_head;
	list_for_each(next, head) {
		p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
		list_del(&p_booked_ticket_id_data->list);
		next = head;
		free(p_booked_ticket_id_data);
	}
	
	memset(&user_info_data, '\0', sizeof(struct user_info));

	fp user info = fopen(USER_INFO_FILE, "ab+");
	if (!fp_user_info) {
		DEBUG("文件打开失败\n");
		return (-TICKET_OPEN_FILE_FAIL);
	}
	
	while (!feof(fp_user_info)) {
		if (fread(&user_info_data, sizeof(struct user_info), 1, fp_user_info)) {
			if (!strcmp(user_info_data.account, account)) {
				*p_user_info = user_info_data;
				for (count = 0; count < OWN_TICKET_MAX; count++) {
					p_booked_ticket_id_data = (struct booked_ticket_id *)
											  malloc(sizeof(struct booked_ticket_id));
					list_add_tail(&p_booked_ticket_id_data->list, p_booked_ticket_id_head);
					strcpy(p_booked_ticket_id_data->ID,
						   p_user_info->own_ticket[count]);
				}

				memset(p_user_info->own_ticket, '\0', OWN_TICKET_MAX*TICKET_ID_LENGTH);
				fclose(fp_user_info);
				return TRUE;
			}
		}
	}

	fclose(fp_user_info);

	return FALSE;
}

int logout_user_info(struct user_info *p_user_info,
					 struct list_head *p_booked_ticket_id_head)
{
	struct list_head *next, *head;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;

	if (!p_user_info || !p_booked_ticket_id_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	save_user_info(p_user_info, p_booked_ticket_id_head);

	p_user_info->own_ticket_count = 0;
	memset(p_user_info->account, '\0', USER_ACCOUNT_LENGTH);

	head = p_booked_ticket_id_head;
	list_for_each(next, head) {
		p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
		list_del(&p_booked_ticket_id_data->list);
		next = head;
		free(p_booked_ticket_id_data);
	}

	return TRUE;
}


static int save_user_info(struct user_info *p_user_info,
						  struct list_head *p_booked_ticket_id_head)
{
	FILE *fp_user_info = NULL;
	struct list_head *next, *head;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;
	uint8_t count = 0;
	struct user_info user_info_data;
	long int offset = 0;

	if (!p_user_info || !p_booked_ticket_id_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	fp_user_info = fopen(USER_INFO_FILE, "ab+");
	if (!fp_user_info) {
		DEBUG("保存用户信息失败,文件打开失败\n");
		return (-TICKET_OPEN_FILE_FAIL);
	}

	head = p_booked_ticket_id_head;
	list_for_each(next, head) {
		p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
		strcpy(p_user_info->own_ticket[count],
			   p_booked_ticket_id_data->id);
		count++;
	}

	while (!feof(fp_user_info)) {
		if (fread(&user_info_data, sizeof(struct user_info), 1, fp_user_info)) {
			if (!strcmp(user_info_data.account, p_user_info->account)) {
				fseek(fp_user_info, -sizeof(struct user_info), SEEK_CUR);
				offset = ftell(fp_user_info);
				break;
			}
		}
		offset = ftell(fp_user_info);
	}

	fclose(fp_user_info);

	fp_user_info = fopen(USER_INFO_FILE, "rb+");
	if (!fp_user_info) {
		DEBUG("保存用户信息失败,文件打开失败\n");
		return (-TICKET_OPEN_FILE_FAIL);
	}
	
	fseek(fp_user_info, offset, SEEK_SET);
	
	if (fwrite(p_user_info, sizeof(struct user_info), 1, fp_user_info) != 1) {
		DEBUG("fwrite error");
		memset(p_user_info->own_ticket, '\0', OWN_TICKET_MAX*TICKET_ID_LENGTH);
		fclose(fp_user_info);
		return(-TICKET_WRITE_FILE_FAIL);
	}

	fclose(fp_user_info);

	memset(p_user_info->own_ticket, '\0', OWN_TICKET_MAX*TICKET_ID_LENGTH);

	return TRUE;
}


int display_user_ticket_ID(struct list_head *p_booked_ticket_id_head)
{
	struct list_head *next, *head;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;

	if(!p_booked_ticket_id_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	head = p_booked_ticket_id_head;
	if (list_empty(p_booked_ticket_id_head)) {
		MOVEDOWN(1);
		printf("暂无");
		return FALSE;
	}
	
	list_for_each(next, head) {
		p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
		printf("%s", p_booked_ticket_id_data->ID);
		MOVEDOWN(1);
		MOVELEFT((int)strlen(p_booked_ticket_id_data->id));
	}

	return TRUE;
}


int display_user_ticket(struct list_head *p_booked_ticket_id_head,
						struct list_head *p_ticket_head)
{
	struct concert_ticket *p_concert_ticket_data = NULL;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;
	struct list_head *next, *head;

	if (!p_booked_ticket_id_head || !p_ticket_head) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	printf("      您已购买的演出:");
	MOVEDOWN(1);
	MOVELEFT(31);
	printf("   ID   艺人   时间   价格");
	MOVEDOWN(2);
	MOVELEFT(36);
	
	head = p_booked_ticket_id_head;
	list_for_each(next, head) {
		p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
		p_concert_ticket_data = locate_concert_ticket(p_ticket_head, p_booked_ticket_id_data->ID);
		printf("   %s   %s   %s   %s",
				p_concert_ticket_data->ID, p_concert_ticket_data->artist,
				p_concert_ticket_data->show_time, p_concert_ticket_data->price);
		MOVEDOWN(2);
		MOVELEFT((int)(strlen(p_concert_ticket_data->ID) + 
					strlen(p_concert_ticket_data->artist) +
					strlen(p_concert_ticket_data->show_time) +
					strlen(p_concert_ticket_data->price)) + 6);
	}
	return TRUE;
}


int book_concert_ticket(struct user_info *p_user_info,
						struct list_head *p_booked_ticket_id_head,
						struct list_head *p_ticket_head,
						char *ID)
{
	int ret;
	int temp_spare_ticket_num;
	struct concert_ticket *p_concert_ticket_data = NULL;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;
	
	if (!p_user_info ||
	    !p_booked_ticket_id_head ||
		!p_ticket_head ||
		!ID ) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	ret = is_ticket_id(ID);
	if (ret == FALSE) {
		printf("门票ID格式错误！\n");
		return FALSE;
	}

	p_concert_ticket_data = locate_concert_ticket(p_ticket_head, ID);
	if (!p_concert_ticket_data) {
		printf("门票不存在\n");
		return FALSE;
	}

	temp_spare_ticket_num = atoi(p_concert_ticket_data->spare_ticket_num);

	if (temp_spare_ticket_num == 0) {
		printf ("票卖光了!\n");
		return FALSE;
	}

	if (p_user_info->own_ticket_count >= OWN_TICKET_MAX) {
		printf("买不了,你最多只能买5张票！\n");
		return FALSE;
	}

	p_booked_ticket_id_data = (struct booked_ticket_id *)malloc(sizeof(struct booked_ticket_id));
	list_add_tail(&p_booked_ticket_id_data->list, p_booked_ticket_id_data);
	strcpy(p_concert_ticket_data->ID, ID);

	temp_spare_ticket_num--;
	p_user_info->own_ticket_count++;

	sprintf(p_concert_ticket_data->spare_ticket_num, "%d", temp_spare_ticket_num);

	ret = save_concert_ticket(p_ticket_head);
	if (ret != TRUE) {
		DEBUG ("门票信息更新失败\n");
		temp_spare_ticket_num++;
		p_user_info->own_ticket_count--;
		printf(p_concert_ticket_data->spare_ticket_num, "%d", temp_spare_ticket_num);
		return FALSE;
	}

	ret = save_user_info(p_user_info, p_booked_ticket_id_head);
	if (ret != TRUE) {
		DEBUG("用户信息更新失败\n");
		temp_spare_ticket_num++;
		p_user_info->own_ticket_count--;
		sprintf(p_concert_ticket_data->spare_ticet_num, "%d", temp_spare_ticket_num);
		return FALSE;
	}

	return TRUE;
}

	
int return_concert_ticket(struct user_info *p_user_info, 
				        struct list_head *p_booked_ticket_id_head, 
						struct list_head *p_ticket_head, 
						char *ID)
{
	int8_t ret = 0;
	int temp_spare_ticket_num;
	struct list_head *next = NULL;
	struct list_head *head = NULL;
	struct concert_ticket *p_concert_ticket_data = NULL;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;

	if (!p_user_info ||
		!p_booked_ticket_id_head || 
		!p_ticket_head || 
		!ID) {
		DEBUG("PARAM ERROR!\n");
		return (-TICKET_PARAM_NULL);
	}

	ret = is_ticket_id(ID);
	if (ret == FALSE)
		return FALSE;

	p_train_ticket_data = locate_train_ticket(p_ticket_head, ID);
	temp_spare_ticket_num = atoi(p_concert_ticket_data->spare_ticket_num);
	if (!p_concert_ticket_data) {
		printf("门票不在列表！\n");
		return FALSE;
	}

	if (p_user_info->own_ticket_count == 0) {
		printf("当前用户没有购买门票!\n");
		return FALSE;
	}

	head = p_booked_ticket_id_head;
	ret = FALSE;
	list_for_each(next, head) {
		p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
		if (!strcmp(p_booked_ticket_id_data->id, id)) {
			list_del(&p_booked_ticket_id_data->list);
			next = head;
			free(p_booked_ticket_id_data);
			ret = TRUE;
			break;
																									}
	}

	if (ret == TRUE) {
		p_user_info->own_ticket_count--;
		temp_spare_ticket_num++;
		sprintf(p_concert_ticket_data->spare_ticket_num, "%d", temp_spare_ticket_num);

		ret = save_concert_ticket(p_ticket_head);
		if (ret != TRUE) {
			DEBUG("门票信息更新失败\n");
			temp_spare_ticket_num--;
			p_user_info->own_ticket_count++;
			sprintf(p_concert_ticket_data->spare_ticket_num, "%d", temp_spare_ticket_num);
			return FALSE;
		}
		
		ret = save_user_info(p_user_info, p_booked_ticket_id_head);
		if (ret != TRUE) {
			DEBUG("用户信息更新失败\n");
			temp_spare_ticket_num--;
			sprintf(p_concert_ticket_data->spare_ticket_num, "%d", temp_spare_ticket_num);
			p_user_info->own_ticket_count++;
			return FALSE;
		}
	
	} else {
		printf("没有购买这张门票\n");
		return FALSE;
	}

	return TRUE;
}


int concert_ticket_destroy(struct list_head *p_ticket_head,
						   struct user_info *p_user_info,
						   struct list_head *p_booked_ticket_id_head)
{
	struct list_head *next = NULL;
	struct list_head *head = NULL;
	struct concert_ticket *p_concert_ticket_data = NULL;
	struct booked_ticket_id *p_booked_ticket_id_data = NULL;

	if (p_ticket_head != NULL) {
		save_concert_ticket(p_ticket_head);

		head = p_ticket_head;
		list_for_each(next, head) {
			p_train_ticket_data = list_entry(next, struct concert_ticket, list);
			list_del(&p_concert_ticket_data->list);
			next = head;
			free(p_concert_ticket_data);
		}
	}

	if (p_user_info != NULL) {
		save_user_info(p_user_info, p_booked_ticket_id_head);

		head = p_booked_ticket_id_head;
		list_for_each(next, head) {
			p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
			list_del(&p_booked_ticket_id_data->list);
			next = head;
			free(p_booked_ticket_id_data);
		}
	} else {
		head = p_booked_ticket_id_head;
		list_for_each(next, head) {
			p_booked_ticket_id_data = list_entry(next, struct booked_ticket_id, list);
			list_del(&p_booked_ticket_id_data->list);
			next = head;
			free(p_booked_ticket_id_data);
		}
	}

	return TRUE;
}


